#ifndef _KkpParton_H_
#define _KkpParton_H_

//
// KkpParton.h
//
// Created by TB on 11/18/11.
// Copyright 2011 BNL. All rights reserved.
//

#include <map>

class TParticlePDG;

namespace tppmc {
   
   namespace kkp {
      
      
      
      // Convert quark KF codes to KKP
      int fromPdg(int);
      
      
      /**
       KKP parton type labelling:
       <ul>
       <li>0: gluon</li>
       <li>1: u</li>
       <li>2: ubar</li>
       <li>3: d</li>
       <li>4: dbar</li>
       <li>5: s</li>
       <li>6: sbar</li>
       <li>7: c</li>
       <li>8: cbar</li>
       <li>9: b</li>
       <li>10: bbar</li>
       </ul>
       */
      enum PartonType {
         GLUON = 0,
         UQUARK,
         UBAR,
         DQUARK,
         DBAR,
         SQUARK,
         SBAR,
         CQUARK,
         CBAR,
         BQUARK,
         BBAR,
         INVALID_PARTON_TYPE
      };

      
      /**
       Parton defined by a numerical code according to the KKP convention,
       with methods to access corresponding PDG information.
       */
      class Parton {
         
      public:
         
         
         /**
          Constructor.
          The input integer must be a PartonType (except INVALID_PARTON_TYPE)
          or the constructor will throw an std::invalid_argument.
          */
         Parton(int = GLUON);
         
         
         virtual ~Parton() { }
         
         
         /**
          Return the PDG code for this parton type.
          */
         virtual int PdgCode() const;
         
         
         /**
          Return the PDG information for this particle.
          */
         virtual TParticlePDG* Pdg() const;
         
         
         virtual operator int() const;
         
         
         /**
          Returns true if the passed value is a valid KKP parton code,
          false otherwise.
          */
         static bool Valid(unsigned);
         
         
         /**
          Conversion from KKP parton code to PDG parton code.
          */
         static int ToPdg(unsigned);
         
         
      protected:
         
         unsigned mKkp;
         int mPdg;
         
      private:
         
         static std::map<unsigned, int> mRelations;
      };
      
      inline Parton::operator int() const {
         return mKkp;
      }
      
   } // namespace kkp
   
} // namespace tppmc

#endif
